﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;

namespace LieroClone
{
    public class Sprite
    {
        public Texture2D sprite;
        public Vector2 pos, size;
        public bool alive;
        public double angle;

        public Sprite()
        {
            sprite = null;
            pos = size = Vector2.Zero;
            alive = false;
            angle = 0;
        }

        public Sprite(Texture2D tex)
        {
            sprite = tex;
            pos = Vector2.Zero;
            size = new Vector2((float)sprite.Width, (float)sprite.Height);
            alive = false;
            angle = 0;
        }

        public Sprite(Texture2D tex, Vector2 loc)
        {
            sprite = tex;
            pos = loc;
            size = new Vector2((float)sprite.Width, (float)sprite.Height);
            alive = false;
            angle = 0;
        }

        public Sprite(Texture2D tex, Vector2 loc, Vector2 dim)
        {
            sprite = tex;
            pos = loc;
            size = dim;
            alive = false;
            angle = 0;
        }

        public Sprite( Texture2D tex, Vector2 loc, double rot )
        {
            sprite = tex;
            pos = loc;
            size = new Vector2((float)sprite.Width, (float)sprite.Height);
            alive = false;
            angle = rot;
        }

        public Sprite(Texture2D tex, Vector2 loc, Vector2 dim, double rot)
        {
            sprite = tex;
            pos = loc;
            size = dim;
            alive = false;
            angle = rot;
        }

        public virtual void draw(SpriteBatch sb)
        {
            sb.Draw(sprite, pos, new Rectangle(0, 0, (int)size.X, (int)size.Y),
                    Color.Red, (float)angle, size / 2, 1.0f, SpriteEffects.None, 0);
        }

        // center is a point representing the center of the screen in world coordinates.
        // This is used to determine if the object is actually in the viewing area because pos is also a
        //      world coordinate.
        public virtual void draw(SpriteBatch sb, Vector2 center, int screen )
        {
            if (!alive)
                return;
            Rectangle view, obj;
            Vector2 tmp = Vector2.Zero;
            switch (screen)
            {
                case 0: // Bottom status bar
                    break;
                case 1: // Left side of screen
                    view = new Rectangle((int)center.X-200, (int)center.Y-250, 400, 500);
                    obj = new Rectangle((int)(pos.X-size.X/2), (int)(pos.Y-size.Y/2), (int)size.X, (int)size.Y);
                    if (view.Intersects(obj) || view.Contains(obj))
                        tmp = new Vector2(obj.X - view.X, obj.Y - view.Y);
                    break;
                case 2: // Right side of screen
                    view = new Rectangle((int)center.X-200, (int)center.Y-250, 400, 500);
                    obj = new Rectangle((int)(pos.X-size.X/2), (int)(pos.Y-size.Y/2), (int)size.X, (int)size.Y);
                    if (view.Intersects(obj) || view.Contains(obj))
                        tmp = new Vector2(obj.X-view.X + 400, obj.Y-view.Y);
                    break;
                default:
                    break;
            }
            sb.Draw(sprite, tmp, new Rectangle( 0, 0, (int)size.X, (int)size.Y),
                    Color.White, (float)angle, size/2, 1.0f, SpriteEffects.None, 0 );
        }

        public virtual int update(double elapsedTime)
        {
            if (!alive)
                return -1;
            return 0;
        }
    }

    public class Projectile : Sprite
    {
        public Vector2 vel;
        public int damage;
        public bool falls;

        public Projectile() : base()
        {
            vel = Vector2.Zero;
            damage = 0;
            falls = false;
        }

        public Projectile(Texture2D tex) : base(tex)
        {
            vel = Vector2.Zero;
            damage = 0;
            falls = false;
        }

        public Projectile(Texture2D tex, Vector2 loc, double rot) : base(tex, loc, rot)
        {
            vel = Vector2.Zero;
            damage = 1;
            falls = false;
        }

        public Projectile(Texture2D tex, Vector2 loc, double rot, int dmg) : base(tex, loc, rot)
        {
            vel = new Vector2(150.0f, 0.0f);
            damage = dmg;
            falls = false;
        }

        public Projectile(Texture2D tex, Vector2 loc, double rot, int dmg, Vector2 speed, bool grav)
            : base(tex, loc, rot)
        {
            vel = speed;
            damage = dmg;
            falls = grav;
        }

        public Projectile(Texture2D tex, Vector2 loc, Vector2 dim, double rot, int dmg, Vector2 speed, bool grav)
            : base(tex, loc, dim, rot)
        {
            vel = speed;
            damage = dmg;
            falls = grav;
        }

        public override int update(double elapsedTime)
        {
            if (!alive)
                return -1;
            if (falls)
                vel.Y += 49.0f * (float)elapsedTime;
            angle = Math.Atan(vel.Y / vel.X);
            pos += vel * (float)elapsedTime;
            if (pos.X < 0 || pos.X > 800 || pos.Y < 0 || pos.Y > 600)
                alive = false;
            return 0;
        }
    }
}
